package com.yang.spring.core.bean.builder;


import com.yang.spring.core.bean.BeanFactory;
import com.yang.spring.core.bean.definition.BeanDefinition;
import com.yang.spring.core.bean.enums.BeanTypeEnum;
import com.yang.spring.core.utils.CollectionUtils;

import java.lang.reflect.InvocationTargetException;
import java.util.List;
import java.util.stream.Collectors;

public class ConfigurationBeanBuilder extends AbstractBeanBuilder {
    @Override
    public Object buildBean(BeanDefinition beanDefinition) throws InstantiationException, IllegalAccessException, InvocationTargetException {
        List<BeanDefinition> dependencyBeanDefinitionList = beanDefinition.getDependencyBeanDefinitionList();
        if (CollectionUtils.isNotEmpty(dependencyBeanDefinitionList)) {
            List<BeanDefinition> notBeanAnnotations = dependencyBeanDefinitionList.stream()
                    .filter(dependencyBeanDefinition -> dependencyBeanDefinition.getBeanType() != BeanTypeEnum.BEAN)
                    .collect(Collectors.toList());
            for (BeanDefinition dependencyBeanDefinition : notBeanAnnotations) {
                Object dependencyInstance = BeanFactory.getBeanByName(dependencyBeanDefinition.getBeanName(), dependencyBeanDefinition.getBeanClassType());
                if (dependencyInstance == null) {
                    dependencyInstance = BeanFactory.buildBeanInstance(dependencyBeanDefinition);
                }
                dependencyBeanDefinition.setInstance(dependencyInstance);
            }
        }
        Class beanClassType = beanDefinition.getBeanClassType();
        Object instance = beanClassType.newInstance();
        beanDefinition.setInstance(instance);
        richBeanDefinition(beanDefinition);

        if (CollectionUtils.isNotEmpty(dependencyBeanDefinitionList)) {
            List<BeanDefinition> beanAnnotations = dependencyBeanDefinitionList.stream()
                    .filter(dependencyBeanDefinition -> dependencyBeanDefinition.getBeanType() == BeanTypeEnum.BEAN)
                    .collect(Collectors.toList());
            for (BeanDefinition dependencyBeanDefinition : beanAnnotations) {
                Object dependencyInstance = BeanFactory.getBeanByName(dependencyBeanDefinition.getBeanName(), dependencyBeanDefinition.getBeanClassType());
                if (dependencyInstance == null) {
                    dependencyInstance = BeanFactory.buildBeanInstance(dependencyBeanDefinition);
                }
                dependencyBeanDefinition.setInstance(dependencyInstance);
            }
        }

        BeanFactory.putBean(beanDefinition, instance);
        return instance;
    }
}
